package com.lastcode6175.bluetoothremotecontrol

import android.Manifest
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothHidDevice
import android.bluetooth.BluetoothHidDeviceAppSdpSettings
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull

private const val CHANNEL_ID = "BluetoothRemoteControlServiceChannel"
private const val NOTIFICATION_ID = 1
private const val ACTION_STOP_SERVICE = "com.lastcode6175.bluetoothremotecontrol.STOP_SERVICE"

// BluetoothConnectionState, BluetoothDeviceInfo, and other constants/descriptors
// These are moved from the ViewModel and are now part of the service.

enum class BluetoothConnectionState {
    DISCONNECTED,
    SCANNING,
    CONNECTING,
    CONNECTED
}

data class BluetoothDeviceInfo(
    val name: String,
    val address: String,
    val isPaired: Boolean = false
)

private object HidReportConstants {
    const val ID_KEYBOARD = 1
    const val ID_MOUSE = 2
    const val ID_CONSUMER_CONTROL = 3
}

enum class ConsumerControlCode(val code: Int) {
    POWER(0x0030), OK(0x0041), HOME(0x0223), BACK(0x0224),
    UP(0x0042), DOWN(0x0043), LEFT(0x0044), RIGHT(0x0045),
    VOLUME_UP(0x00E9), VOLUME_DOWN(0x00EA), MUTE(0x00E2),
    VOICE_ASSISTANT(0x0221)
}

private object HidReportDescriptor {
    private val DESCRIPTOR = byteArrayOf(
        0x05.toByte(), 0x01.toByte(),       // Usage Page (Generic Desktop)
        0x09.toByte(), 0x06.toByte(),       // Usage (Keyboard)
        0xA1.toByte(), 0x01.toByte(),       // Collection (Application)
        0x85.toByte(), HidReportConstants.ID_KEYBOARD.toByte(), //   Report ID (1)
        0x05.toByte(), 0x07.toByte(),       //   Usage Page (Keyboard/Keypad)
        0x19.toByte(), 0xE0.toByte(),       //   Usage Minimum (Keyboard LeftControl)
        0x29.toByte(), 0xE7.toByte(),       //   Usage Maximum (Keyboard Right GUI)
        0x15.toByte(), 0x00.toByte(),       //   Logical Minimum (0)
        0x25.toByte(), 0x01.toByte(),       //   Logical Maximum (1)
        0x75.toByte(), 0x01.toByte(),       //   Report Size (1)
        0x95.toByte(), 0x08.toByte(),       //   Report Count (8)
        0x81.toByte(), 0x02.toByte(),       //   Input (Data, Var, Abs) -> Modifier Keys
        0x95.toByte(), 0x01.toByte(),       //   Report Count (1)
        0x75.toByte(), 0x08.toByte(),       //   Report Size (8)
        0x81.toByte(), 0x01.toByte(),       //   Input (Const, Var, Abs) -> Reserved Byte
        0x95.toByte(), 0x06.toByte(),       //   Report Count (6)
        0x75.toByte(), 0x08.toByte(),       //   Report Size (8)
        0x15.toByte(), 0x00.toByte(),       //   Logical Minimum (0)
        0x25.toByte(), 0x65.toByte(),       //   Logical Maximum (101)
        0x05.toByte(), 0x07.toByte(),       //   Usage Page (Keyboard/Keypad)
        0x19.toByte(), 0x00.toByte(),       //   Usage Minimum (Reserved (no event indicated))
        0x29.toByte(), 0x65.toByte(),       //   Usage Maximum (Keyboard Application)
        0x81.toByte(), 0x00.toByte(),       //   Input (Data, Ary, Abs) -> Keycodes
        0xC0.toByte(),                     // End Collection

        // Mouse Collection
        0x05.toByte(), 0x01.toByte(),       // Usage Page (Generic Desktop)
        0x09.toByte(), 0x02.toByte(),       // Usage (Mouse)
        0xA1.toByte(), 0x01.toByte(),       // Collection (Application)
        0x85.toByte(), HidReportConstants.ID_MOUSE.toByte(),    //   Report ID (2)
        0x09.toByte(), 0x01.toByte(),       //   Usage (Pointer)
        0xA1.toByte(), 0x00.toByte(),       //   Collection (Physical)
        0x05.toByte(), 0x09.toByte(),       //     Usage Page (Button)
        0x19.toByte(), 0x01.toByte(),       //     Usage Minimum (Button 1)
        0x29.toByte(), 0x03.toByte(),       //     Usage Maximum (Button 3)
        0x15.toByte(), 0x00.toByte(),       //     Logical Minimum (0)
        0x25.toByte(), 0x01.toByte(),       //     Logical Maximum (1)
        0x95.toByte(), 0x03.toByte(),       //     Report Count (3)
        0x75.toByte(), 0x01.toByte(),       //     Report Size (1)
        0x81.toByte(), 0x02.toByte(),       //     Input (Data, Var, Abs) -> Buttons
        0x95.toByte(), 0x01.toByte(),       //     Report Count (1)
        0x75.toByte(), 0x05.toByte(),       //     Report Size (5)
        0x81.toByte(), 0x01.toByte(),       //     Input (Const, Var, Abs) -> Padding
        0x05.toByte(), 0x01.toByte(),       //     Usage Page (Generic Desktop)
        0x09.toByte(), 0x30.toByte(),       //     Usage (X)
        0x09.toByte(), 0x31.toByte(),       //     Usage (Y)
        0x09.toByte(), 0x38.toByte(),       //     Usage (Wheel)
        0x15.toByte(), 0x81.toByte(),       //     Logical Minimum (-127)
        0x25.toByte(), 0x7F.toByte(),       //     Logical Maximum (127)
        0x75.toByte(), 0x08.toByte(),       //     Report Size (8)
        0x95.toByte(), 0x03.toByte(),       //     Report Count (3)
        0x81.toByte(), 0x06.toByte(),       //     Input (Data, Var, Rel) -> X, Y, Wheel
        0xC0.toByte(),                     //   End Collection
        0xC0.toByte(),                     // End Collection

        // Consumer Control Collection
        0x05.toByte(), 0x0C.toByte(),       // Usage Page (Consumer)
        0x09.toByte(), 0x01.toByte(),       // Usage (Consumer Control)
        0xA1.toByte(), 0x01.toByte(),       // Collection (Application)
        0x85.toByte(), HidReportConstants.ID_CONSUMER_CONTROL.toByte(), //   Report ID (3)
        0x19.toByte(), 0x00.toByte(),       //   Usage Minimum (0)
        0x2A.toByte(), 0x3C.toByte(), 0x02.toByte(), // Usage Maximum (0x23C)
        0x15.toByte(), 0x00.toByte(),       //   Logical Minimum (0)
        0x26.toByte(), 0x3C.toByte(), 0x02.toByte(), // Logical Maximum (0x23C)
        0x95.toByte(), 0x01.toByte(),       //   Report Count (1)
        0x75.toByte(), 0x10.toByte(),      //   Report Size (16)
        0x81.toByte(), 0x00.toByte(),       //   Input (Data, Ary, Abs)
        0xC0.toByte()                      // End Collection
    )

    fun getDescriptor(): ByteArray = DESCRIPTOR

    fun asciiToHid(char: Char): Pair<Byte, Byte> {
        var modifier: Byte = 0
        val keyCode: Byte = when (char) {
            in 'a'..'z' -> (char - 'a' + 0x04).toByte()
            in 'A'..'Z' -> {
                modifier = 0x02; (char - 'A' + 0x04).toByte()
            }
            in '1'..'9' -> (char - '1' + 0x1E).toByte()
            '0' -> 0x27
            ' ' -> 0x2C
            '\n' -> 0x28
            '!' -> { modifier = 0x02; 0x1E }
            '@' -> { modifier = 0x02; 0x1F }
            '#' -> { modifier = 0x02; 0x20 }
            '$' -> { modifier = 0x02; 0x21 }
            '%' -> { modifier = 0x02; 0x22 }
            '^' -> { modifier = 0x02; 0x23 }
            '&' -> { modifier = 0x02; 0x24 }
            '*' -> { modifier = 0x02; 0x25 }
            '(' -> { modifier = 0x02; 0x26 }
            ')' -> { modifier = 0x02; 0x27 }
            else -> 0x00
        }
        return Pair(keyCode, modifier)
    }
}

@SuppressLint("MissingPermission")
class BluetoothService : Service(), BluetoothServiceApi {

    inner class LocalBinder : Binder() {
        fun getService(): BluetoothService = this@BluetoothService
    }

    private val binder = LocalBinder()
    private val serviceScope = CoroutineScope(Dispatchers.Default)

    private val bluetoothManager by lazy { getSystemService(BLUETOOTH_SERVICE) as BluetoothManager }
    private val bluetoothAdapter: BluetoothAdapter? by lazy { bluetoothManager.adapter }

    private val _state = MutableStateFlow(BluetoothConnectionState.DISCONNECTED)
    override val state: StateFlow<BluetoothConnectionState> = _state.asStateFlow()

    private val _availableDevices = MutableStateFlow<List<BluetoothDeviceInfo>>(emptyList())
    override val availableDevices: StateFlow<List<BluetoothDeviceInfo>> = _availableDevices.asStateFlow()

    private val _connectedDeviceName = MutableStateFlow("")
    override val connectedDeviceName: StateFlow<String> = _connectedDeviceName.asStateFlow()

    private val _permissionRequest = MutableSharedFlow<Array<String>>()
    override val permissionRequest: MutableSharedFlow<Array<String>> = _permissionRequest

    private val _errorMessage = MutableStateFlow<String?>(null)
    override val errorMessage: StateFlow<String?> = _errorMessage.asStateFlow()

    private var bluetoothHidDevice: BluetoothHidDevice? = null
    private var connectedHostDevice: BluetoothDevice? = null
    private var hidSetupComplete: CompletableDeferred<Boolean>? = null

    override fun onBind(intent: Intent): IBinder = binder

    override fun onCreate() {
        super.onCreate()
        startForegroundService()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if (intent?.action == ACTION_STOP_SERVICE) {
            cleanupAndStopService()
            return START_NOT_STICKY
        }
        return START_STICKY
    }

    override fun onDestroy() {
        super.onDestroy()
        cleanup()
    }

    private val profileListener = object : BluetoothProfile.ServiceListener {
        override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
            if (profile == BluetoothProfile.HID_DEVICE) {
                bluetoothHidDevice = proxy as BluetoothHidDevice
                registerHidApp()
            }
        }
        override fun onServiceDisconnected(profile: Int) {
            if (profile == BluetoothProfile.HID_DEVICE) {
                bluetoothHidDevice = null
                hidSetupComplete = null
                _state.value = BluetoothConnectionState.DISCONNECTED
            }
        }
    }

    private fun registerHidApp() {
        try {
            val sdpRecord = BluetoothHidDeviceAppSdpSettings(
                "蓝牙遥控器", "模拟远程输入设备", "LastCode6175",
                BluetoothHidDevice.SUBCLASS2_REMOTE_CONTROL, HidReportDescriptor.getDescriptor()
            )
            bluetoothHidDevice?.registerApp(sdpRecord, null, null, mainExecutor, hidCallback)

            serviceScope.launch {
                delay(5000)
                if (hidSetupComplete?.isActive == true) {
                    hidSetupComplete?.complete(false)
                    _errorMessage.value = "HID注册超时"
                }
            }
        } catch (e: Exception) {
            hidSetupComplete?.complete(false)
            _errorMessage.value = "HID注册失败: ${e.message}"
        }
    }

    private val hidCallback = object : BluetoothHidDevice.Callback() {
        override fun onAppStatusChanged(pluggedDevice: BluetoothDevice?, registered: Boolean) {
            if (hidSetupComplete?.isActive == true) {
                hidSetupComplete?.complete(registered)
                if (!registered) {
                    _errorMessage.value = "HID应用注册失败"
                }
            }
        }

        override fun onConnectionStateChanged(device: BluetoothDevice, state: Int) {
            when (state) {
                BluetoothProfile.STATE_CONNECTED -> {
                    _state.value = BluetoothConnectionState.CONNECTED
                    _connectedDeviceName.value = device.name ?: "已连接设备"
                    connectedHostDevice = device
                    updateNotification("已连接到 ${device.name}")
                }
                BluetoothProfile.STATE_DISCONNECTED -> {
                    _state.value = BluetoothConnectionState.DISCONNECTED
                    _connectedDeviceName.value = ""
                    connectedHostDevice = null
                    updateNotification("连接已断开")
                }
                BluetoothProfile.STATE_CONNECTING -> {
                    _state.value = BluetoothConnectionState.CONNECTING
                    updateNotification("正在连接...")
                }
            }
        }
    }

    fun startHidSetup(): CompletableDeferred<Boolean> {
        if (hidSetupComplete?.isActive == true) return hidSetupComplete!!
        hidSetupComplete = CompletableDeferred()

        val adapter = bluetoothAdapter
        if (adapter == null) {
            _errorMessage.value = "蓝牙适配器不可用"
            hidSetupComplete?.complete(false)
            return hidSetupComplete!!
        }

        if (!adapter.isEnabled) {
            hidSetupComplete?.complete(false)
            _errorMessage.value = "请先开启蓝牙"
            return hidSetupComplete!!
        }

        if (!checkPermissions()) {
            hidSetupComplete?.complete(false)
            return hidSetupComplete!!
        }

        adapter.getProfileProxy(this, profileListener, BluetoothProfile.HID_DEVICE)

        serviceScope.launch {
            delay(10000)
            if (hidSetupComplete?.isActive == true) {
                hidSetupComplete?.complete(false)
                _errorMessage.value = "HID设备初始化超时"
            }
        }
        return hidSetupComplete!!
    }

    override fun scanDevices() {
        val adapter = bluetoothAdapter
        if (adapter == null) {
            _errorMessage.value = "蓝牙适配器不可用"
            return
        }

        if (!adapter.isEnabled) {
            _errorMessage.value = "请先开启蓝牙"
            return
        }
        if (!checkPermissions()) return

        serviceScope.launch {
            // 立即显示已配对设备，不等待扫描完成
            val bondedDevices = adapter.bondedDevices
            _availableDevices.value = bondedDevices?.filter { device ->
                device.bluetoothClass?.let {
                    val majorDeviceClass = it.majorDeviceClass
                    majorDeviceClass == android.bluetooth.BluetoothClass.Device.Major.COMPUTER || 
                    majorDeviceClass == android.bluetooth.BluetoothClass.Device.Major.PHONE
                } ?: false
            }?.map {
                BluetoothDeviceInfo(it.name ?: "已配对设备", it.address, true)
            } ?: emptyList()

            // 如果已经在扫描中，不需要重新开始扫描
            if (adapter.isDiscovering) {
                return@launch
            }

            // 开始异步扫描
            _state.value = BluetoothConnectionState.SCANNING
            
            try {
                // 注册广播接收器前先尝试取消注册，避免重复注册
                try {
                    unregisterReceiver(discoveryReceiver)
                } catch (_: Exception) {}
                
                val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
                filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
                registerReceiver(discoveryReceiver, filter)
                
                // 取消之前的扫描并开始新的扫描
                if (adapter.isDiscovering) {
                    adapter.cancelDiscovery()
                }
                adapter.startDiscovery()
            } catch (e: Exception) {
                _errorMessage.value = "扫描设备时出错: ${e.message}"
                _state.value = BluetoothConnectionState.DISCONNECTED
            }
        }
    }

    override fun connectToDevice(deviceInfo: BluetoothDeviceInfo) {
        if (!checkPermissions()) return
        
        // 如果已经连接到相同设备，不需要重新连接
        if (_state.value == BluetoothConnectionState.CONNECTED && 
            _connectedDeviceName.value == deviceInfo.name) {
            return
        }

        serviceScope.launch {
            // 先断开当前连接的设备
            disconnectCurrentDevice()
            
            // 等待断开连接完成
            var waitCount = 0
            while (_state.value != BluetoothConnectionState.DISCONNECTED && waitCount < 10) {
                delay(100)
                waitCount++
            }
            
            _state.value = BluetoothConnectionState.CONNECTING
            _connectedDeviceName.value = deviceInfo.name

            val success = withTimeoutOrNull(20000) {
                val adapter = bluetoothAdapter
                if (adapter == null) {
                    return@withTimeoutOrNull false
                }
                val device = adapter.getRemoteDevice(deviceInfo.address) ?: return@withTimeoutOrNull false

                if (device.bondState != BluetoothDevice.BOND_BONDED) {
                    val paired = triggerPairingAndWait(device)
                    if (!paired) return@withTimeoutOrNull false
                }

                val setupSuccess = hidSetupComplete?.await() ?: startHidSetup().await()

                if (!setupSuccess) {
                    _state.value = BluetoothConnectionState.DISCONNECTED
                    _errorMessage.value = "无法初始化HID设备，请重试"
                    return@withTimeoutOrNull false
                }

                bluetoothHidDevice?.connect(device)
                return@withTimeoutOrNull true
            }

            if (success != true) {
                _state.value = BluetoothConnectionState.DISCONNECTED
                _errorMessage.value = "连接超时或失败，请重试"
            }
        }
    }
    
    /**
      * 断开当前连接的设备
      */
     private fun disconnectCurrentDevice() {
         connectedHostDevice?.let { device ->
             bluetoothHidDevice?.disconnect(device)
             Log.d("BluetoothService", "断开设备连接: ${device.name}")
         }
     }

    private suspend fun triggerPairingAndWait(device: BluetoothDevice): Boolean {
        val pairingResult = CompletableDeferred<Boolean>()
        val bondStateReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                if (intent.action == BluetoothDevice.ACTION_BOND_STATE_CHANGED) {
                    val changedDevice: BluetoothDevice = intent.getParcelableExtraCompat(BluetoothDevice.EXTRA_DEVICE) ?: return
                    if (changedDevice.address == device.address) {
                        when (device.bondState) {
                            BluetoothDevice.BOND_BONDED -> {
                                if (!pairingResult.isCompleted) pairingResult.complete(true)
                                try { context.unregisterReceiver(this) } catch (_: Exception) {}
                            }
                            BluetoothDevice.BOND_NONE -> {
                                if (!pairingResult.isCompleted) pairingResult.complete(false)
                                try { context.unregisterReceiver(this) } catch (_: Exception) {}
                            }
                        }
                    }
                }
            }
        }
        registerReceiver(bondStateReceiver, IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED))
        device.createBond()
        return pairingResult.await()
    }

    override fun sendAsciiKeyPress(key: Char) {
        val (keyCode, modifier) = HidReportDescriptor.asciiToHid(key)
        if (keyCode == 0x00.toByte()) return
        val report = byteArrayOf(modifier, 0x00, keyCode, 0x00, 0x00, 0x00, 0x00, 0x00)
        sendReport(HidReportConstants.ID_KEYBOARD, report)
        val emptyReport = ByteArray(8)
        sendReport(HidReportConstants.ID_KEYBOARD, emptyReport)
    }

    override fun sendMouseMove(dx: Int, dy: Int) {
        val report = byteArrayOf(0x00, dx.coerceIn(-127, 127).toByte(), dy.coerceIn(-127, 127).toByte(), 0x00)
        sendReport(HidReportConstants.ID_MOUSE, report)
    }

    override fun sendMouseClick() {
        sendReport(HidReportConstants.ID_MOUSE, byteArrayOf(0x01, 0x00, 0x00, 0x00))
        sendReport(HidReportConstants.ID_MOUSE, byteArrayOf(0x00, 0x00, 0x00, 0x00))
    }
    
    override fun sendMouseScroll(amount: Int) {
        sendReport(HidReportConstants.ID_MOUSE, byteArrayOf(0x00, 0x00, 0x00, amount.coerceIn(-127, 127).toByte()))
        sendReport(HidReportConstants.ID_MOUSE, byteArrayOf(0x00, 0x00, 0x00, 0x00))
    }

    private fun sendConsumerControl(code: ConsumerControlCode) {
        val report = ByteArray(2)
        report[0] = (code.code and 0xFF).toByte()
        report[1] = (code.code shr 8).toByte()
        sendReport(HidReportConstants.ID_CONSUMER_CONTROL, report)
        val emptyReport = ByteArray(2)
        sendReport(HidReportConstants.ID_CONSUMER_CONTROL, emptyReport)
    }

    override fun sendDpad(direction: ConsumerControlCode) = sendConsumerControl(direction)
    override fun sendOkKey() = sendConsumerControl(ConsumerControlCode.OK)
    override fun sendBackKey() = sendConsumerControl(ConsumerControlCode.BACK)
    override fun sendHomeKey() = sendConsumerControl(ConsumerControlCode.HOME)
    override fun sendPowerKey() = sendConsumerControl(ConsumerControlCode.POWER)
    override fun sendVolumeUp() = sendConsumerControl(ConsumerControlCode.VOLUME_UP)
    override fun sendVolumeDown() = sendConsumerControl(ConsumerControlCode.VOLUME_DOWN)

    override fun sendMute() = sendConsumerControl(ConsumerControlCode.MUTE)

    override fun sendBackspace() {
        sendReport(HidReportConstants.ID_KEYBOARD, byteArrayOf(0, 0, 0x2a, 0, 0, 0, 0, 0)) // Backspace
        sendReport(HidReportConstants.ID_KEYBOARD, ByteArray(8))
    }

    override fun sendEnter() {
        sendReport(HidReportConstants.ID_KEYBOARD, byteArrayOf(0, 0, 0x28, 0, 0, 0, 0, 0)) // Enter
        sendReport(HidReportConstants.ID_KEYBOARD, ByteArray(8))
    }


    override fun sendVoiceAssistant() = sendConsumerControl(ConsumerControlCode.VOICE_ASSISTANT)

    private val discoveryReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                BluetoothDevice.ACTION_FOUND -> {
                    val device: BluetoothDevice = intent.getParcelableExtraCompat(BluetoothDevice.EXTRA_DEVICE) ?: return
                    device.bluetoothClass?.let { bluetoothClass ->
                        val majorDeviceClass = bluetoothClass.majorDeviceClass
                        // 仅显示支持HID控制协议的设备（PC、智能手机和平板电脑）
                        if (majorDeviceClass == android.bluetooth.BluetoothClass.Device.Major.COMPUTER || 
                            majorDeviceClass == android.bluetooth.BluetoothClass.Device.Major.PHONE) {
                            val deviceInfo = BluetoothDeviceInfo(device.name ?: "未知设备", device.address)
                            // 实时更新设备列表，避免重复添加
                            if (_availableDevices.value.none { it.address == deviceInfo.address }) {
                                _availableDevices.value = _availableDevices.value + deviceInfo
                            }
                        }
                    }
                }
                BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
                    // 扫描完成后保持SCANNING状态，这样UI会继续显示扫描指示器
                    // 不要立即将状态设置为DISCONNECTED，这会导致UI闪烁
                    if (_state.value == BluetoothConnectionState.SCANNING) {
                        // 如果当前没有连接设备，则设置为DISCONNECTED
                        if (_connectedDeviceName.value.isEmpty()) {
                            _state.value = BluetoothConnectionState.DISCONNECTED
                        }
                    }
                    // 不要注销接收器，这样可以继续接收设备发现事件
                }
            }
        }
    }

    private fun sendReport(id: Int, data: ByteArray) {
        val device = connectedHostDevice ?: return
        val hidDevice = bluetoothHidDevice ?: return
        hidDevice.sendReport(device, id, data)
    }


    private fun cleanup() {
        bluetoothAdapter?.let { adapter ->
            if (adapter.isDiscovering) {
                adapter.cancelDiscovery()
            }
        }
        try {
            unregisterReceiver(discoveryReceiver)
        } catch (_: Exception) { }

        connectedHostDevice?.let {
            bluetoothHidDevice?.disconnect(it)
        }

        if (bluetoothHidDevice != null) {
            try {
                bluetoothHidDevice?.unregisterApp()
            } catch (_: Exception) { }

            try {
                bluetoothAdapter?.closeProfileProxy(BluetoothProfile.HID_DEVICE, bluetoothHidDevice)
            } catch (_: Exception) { }
        }

        if (hidSetupComplete?.isActive == true) {
            hidSetupComplete?.cancel()
        }
        _state.value = BluetoothConnectionState.DISCONNECTED
    }

    private fun cleanupAndStopService() {
        cleanup()
        stopForeground(STOP_FOREGROUND_REMOVE)

        stopSelf()
    }

    private fun startForegroundService() {
        createNotificationChannel()

        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
            PendingIntent.FLAG_IMMUTABLE)

        val stopSelf = Intent(this, BluetoothService::class.java).apply {
            action = ACTION_STOP_SERVICE
        }
        val pStopSelf = PendingIntent.getService(this, 0, stopSelf, PendingIntent.FLAG_IMMUTABLE)

        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("蓝牙遥控器正在运行")
            .setContentText("等待连接")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentIntent(pendingIntent)
            .addAction(R.drawable.ic_launcher_foreground, "断开并退出", pStopSelf)
            .setOngoing(true)
            .build()

        startForeground(NOTIFICATION_ID, notification)
    }

    private fun createNotificationChannel() {
        val serviceChannel = NotificationChannel(
            CHANNEL_ID,
            "蓝牙遥控器服务",
            NotificationManager.IMPORTANCE_DEFAULT
        )
        val manager = getSystemService(NotificationManager::class.java)
        manager.createNotificationChannel(serviceChannel)
    }

    private fun updateNotification(contentText: String) {
        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)

        val stopSelf = Intent(this, BluetoothService::class.java).apply {
            action = ACTION_STOP_SERVICE
        }
        val pStopSelf = PendingIntent.getService(this, 0, stopSelf, PendingIntent.FLAG_IMMUTABLE)


        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("蓝牙遥控器")
            .setContentText(contentText)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentIntent(pendingIntent)
            .addAction(R.drawable.ic_launcher_foreground, "断开并退出", pStopSelf)
            .setOngoing(true)
            .build()
        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(NOTIFICATION_ID, notification)
    }

    override fun checkPermissions(): Boolean {
        val requiredPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)
        } else {
            arrayOf(Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_FINE_LOCATION)
        }
        val missing = requiredPermissions.filter { ActivityCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }
        return if (missing.isNotEmpty()) {
            serviceScope.launch { _permissionRequest.emit(missing.toTypedArray()) }
            false
        } else {
            true
        }
    }

    private fun Intent.getParcelableExtraCompat(key: String): BluetoothDevice? =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            getParcelableExtra(key, BluetoothDevice::class.java)
        } else {
            @Suppress("DEPRECATION")
            getParcelableExtra(key)
        }

    override fun clearErrorMessage() {
        _errorMessage.value = null
    }
}